package com.gitee.yusugar.core.coder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

/**
 * @author Y-sugar
 */
public class EDECoder {

    private static final String ENCRYPTION_SIGNATURE = "Y-sugar";

    /**
     * AES加密字符串
     *
     * @param content 需要被加密的内容
     * @return 密文
     */
    public static String getAESStr( String content ) {
        try {
            return createContent( content, Cipher.ENCRYPT_MODE );
        } catch ( Exception e ) {
            return null;
        }
    }

    /**
     * 解密AES加密过的字符串
     *
     * @param str AES密文
     * @return 明文
     */
    public static String getAESContent( String str ) {
        try {
            return createContent( str, Cipher.DECRYPT_MODE );
        } catch ( Exception e ) {
            return null;
        }
    }

    private static String createContent( String content, Integer num ) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance( "AES" );
        kgen.init( 128, new SecureRandom( ENCRYPTION_SIGNATURE.getBytes() ) );
        SecretKey secretKey = kgen.generateKey();
        byte[] enCodeFormat = secretKey.getEncoded();
        SecretKeySpec key = new SecretKeySpec( enCodeFormat, "AES" );
        byte[] bytes;
        boolean flag = ( num == Cipher.ENCRYPT_MODE );
        if ( flag )
            bytes = content.getBytes( StandardCharsets.UTF_8 );
        else
            bytes = parseHexStr2Byte( content );

        Cipher cipher = Cipher.getInstance( "AES" );
        cipher.init( num, key );

        return ( flag ? parseByte2HexStr( cipher.doFinal( bytes ) ) : new String( cipher.doFinal( bytes ) ) );
    }

    private static String parseByte2HexStr( byte[] buf ) {
        StringBuilder sb = new StringBuilder();
        for ( byte b : buf ) {
            String hex = Integer.toHexString( b & 0xFF );
            if ( hex.length() == 1 )
                hex = '0' + hex;
            sb.append( hex );
        }
        return sb.toString();
    }

    private static byte[] parseHexStr2Byte( String hexStr ) {
        byte[] result = new byte[hexStr.length() / 2];
        for ( int i = 0; i < hexStr.length() / 2; i++ ) {
            int high = Integer.parseInt( hexStr.substring( i * 2, i * 2 + 1 ), 16 );
            int low = Integer.parseInt( hexStr.substring( i * 2 + 1, i * 2 + 2 ), 16 );
            result[i] = (byte) ( high * 16 + low );
        }
        return result;
    }

    /**
     * 将加密后的字节数组转换成字符串
     *
     * @param b 字节数组
     * @return 字符串
     */
    private static String byteArrayToHexString( byte[] b ) {
        StringBuilder hs = new StringBuilder();
        String stmp;
        for ( int n = 0; b != null && n < b.length; n++ ) {
            stmp = Integer.toHexString( b[n] & 0XFF );
            if ( stmp.length() == 1 )
                hs.append( '0' );
            hs.append( stmp );
        }
        return hs.toString().toLowerCase();
    }

    /**
     * sha256_HMAC加密
     *
     * @param userCode 需要加密的内容
     * @return 加密后的 字符串
     */
    public static String getSHA256Str( String userCode ) {
        try {
            Mac sha256_HMAC = Mac.getInstance( "HmacSHA256" );
            SecretKeySpec secret_key = new SecretKeySpec( ENCRYPTION_SIGNATURE.getBytes(), "HmacSHA256" );
            sha256_HMAC.init( secret_key );
            byte[] bytes = sha256_HMAC.doFinal( userCode.getBytes() );
            //获取到加密后的签名
            return byteArrayToHexString( bytes );
        }catch ( Exception e ) {
            return null;
        }
    }

}
